package com.ld.service;

import com.ld.dao.DBUtilDao;
import com.ld.dao.UserDao;
import com.ld.entity.Country;
import com.ld.entity.Customer;
import com.ld.entity.Staff;
import com.ld.entity.UserFile;
import com.ld.util.SaltUtil;
import org.apache.commons.io.FilenameUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;


@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {

    @Resource(name = "userDao")
    private UserDao userDao;

    @Resource(name = "DBUtilDao")
    private DBUtilDao dbUtilDao;

    /**
     *
     * @param userName 账号
     * @return `
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public Staff staffLogin(String userName) {
        return userDao.staffLogin(userName);
    }

    /**
     * @param userName 账号
     * @param oldPwd   原密码
     * @param newPwd   新密码
     * @return 提示信息
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public String changePwd(String userName, String oldPwd, String newPwd) {
        Staff staff = staffLogin(userName);//本类的方法
        if (staff != null) {
            //前端传来的原始密码+盐
            String oldPwdHashHex = SaltUtil.getHashHex(oldPwd, staff.getSalt());
            if (staff.getPassWord().equals(oldPwdHashHex)) {
                //新的盐
                String newSalt = SaltUtil.getSalt(16);
                //新的密码+盐
                newPwd = SaltUtil.getHashHex(newPwd, newSalt);
                Integer affertLine = userDao.changePwd(staff.getStaffId(), newPwd, newSalt);
                if (affertLine == 1) {
                    return "success";
                }
                return "修改失败,请联系管理员";
            }
            return "原始密码错误";
        }
        return "无此账号";
    }


    /**
     * @param customerId 客户id
     * @return 此客户的详细信息
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public Customer getCustomerInfoByCustomerId(Integer customerId) {
        return userDao.getCustomerInfoByCustomerId(customerId);
    }

    /**
     * @param staffId 员工id
     * @return 返回该员工的详细, 不应包括(密码, 盐, 权限)
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public Staff getStaffInfoByStaffId(Integer staffId) {
        return userDao.getStaffInfoByStaffId(staffId);
    }

    /**
     * @param userName 员工账号
     * @return 返回该员工的详细, 不应包括(密码, 盐, 权限)
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public Staff getStaffInfoByStaffUserName(String userName) {
        return userDao.getStaffInfoByStaffUserName(userName);
    }

    /**
     * @return 查询所有国家, 每个国家对应多个城市
     */
    public List<Country> getAllCountryAndCity() {
        return dbUtilDao.getAllCountryAndCity();
    }


    /**
     * 修改员工信息
     * @param staff 员工实体类
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public String changeStaffInfo(Staff staff) {
        Integer staffTab ;
        Integer addressTab ;
        //有这几个字段则表示需要更新staff表,其中userName作为账号不可更改
        if (staff.getUserName() != null && (staff.getFirstName() != null || staff.getLastName() != null || staff.getEmail() != null)) {
            staffTab = userDao.changeStaffTab(staff);
            if (staffTab <= 0) { //手动回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return "更新staffTab失败";
            }
        }
        //修改address表中的字段:address, address2, district, city_id, postal_code, phone
        if (staff.getAddressId() != null && (staff.getAddress1() != null || staff.getAddress2() != null || staff.getDistrict() != null
                || staff.getPostalCode() != null || staff.getPhone() != null || staff.getCityId() != null)) {

            addressTab = userDao.changeAddressTab(staff);
            if (addressTab <= 0) { //手动回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return "更新addressTab失败";
            }
        }

        return "更新成功";
    }

    /**
     * 上传头像,先根据账号查该用户是否有头像,有则update,无则insert
     * @param userName 账号
     * @MultipartFile photo 传过来的图片
     * @return 成功与否的信息
     */
    @Transactional
    public String uploadHeadPhoto(MultipartFile photo,String userName){
        try {
            //动态获取static目录的绝对路径mysql_sakila\src\main\resources\static
            String realPath = ResourceUtils.getURL("user_files").getPath();
            File fileDir =new File(realPath);
            //查看这个文件夹存在否，不存在则创建
            if (!fileDir.exists()) {
               fileDir.mkdirs();
            }
            UserFile userFile = new UserFile();
            //文件拥有者的账号
            userFile.setUserName(userName);
            //获取文件大小(字节)
            userFile.setSize(String.valueOf(photo.getSize()));
            //获取文件类型,格式如image/jpeg
            userFile.setType(photo.getContentType());
            //文件路径(classpath:static/user_files/目录)
            userFile.setPath("/user_files/");
            //下载次数
            userFile.setDowncount(0);
            //获取原始文件名,带后缀
            userFile.setOldName(photo.getOriginalFilename());
            //是否是图片
            userFile.setIsImg((short) 1);
            //是否是头像(一人只能一张头像,其他不做限制)
            userFile.setIsHeadPhoto((short) 1);
            //获取文件后缀
            String ext="."+FilenameUtils.getExtension(photo.getOriginalFilename());
            userFile.setExt(ext);
            //新文件名 uuid+时间戳+文件后缀
            String uuid = UUID.randomUUID().toString().replace("-", "");
            String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            userFile.setNewName(uuid+timestamp+ext);

            //该用户是否有头像,有则1,无则0
            UserFile hasPhoto = userDao.hasHeadPhoto(userName);
            Session session = SecurityUtils.getSubject().getSession();
            //此用户没有头像,insert操作
            if (hasPhoto==null){
                //把文件上传到static/user_files/目录下,以 新文件名.后缀存放
              photo.transferTo(new File(fileDir,userFile.getNewName()));
              //把文件信息存入数据库 insert操作
                Integer row = userDao.insertFileInfo(userFile);
                if (row==1){
                    //更新session中的头像地址
                    session.setAttribute("loginUserPhoto",userFile.getPath()+userFile.getNewName());
                   return  "上传成功";
                }
            }else {//此用户已有头像,update操作
                //先删除原来的文件
                File oldFile =new File(fileDir,hasPhoto.getNewName());
                boolean delete = oldFile.delete();
                if (delete){//删除成功
                    //把文件上传到static/user_files/目录下,以 新文件名.后缀存放
                    photo.transferTo(new File(fileDir,userFile.getNewName()));
                    //把文件信息存入数据库 update操作 ,根据fileId,因为userName(账号下可能有多个文件),但fileId唯一
                    userFile.setFileId(hasPhoto.getFileId());
                    Integer row = userDao.updateFileInfo(userFile);
                    if (row==1){
                        //更新session中的头像地址
                        session.setAttribute("loginUserPhoto",userFile.getPath()+userFile.getNewName());
                        return  "更新成功!";
                    }
                }
            }
            return "上传/更新失败";
        }catch (Exception e){
            e.printStackTrace();
            return "程序出错";
        }

    }


}
